package echecs.tools;

public final class Square implements Comparable<Square> {

    public static final int FILE_COUNT = 8;
    public static final int RANK_COUNT = 8;
    private static final Square[] SQUARES;
    private final int _file;
    private final int _rank;
    private final transient int _index;
    private final transient String _string;
    private final transient String _fenString;

    static {
        SQUARES = new Square[FILE_COUNT * RANK_COUNT];
        int i = 0;
        for (int y = 0; y < RANK_COUNT; y++) {
            for (int x = 0; x < FILE_COUNT; x++) {
                SQUARES[i++] = new Square(x, y);
            }
        }
    }

    private Square(final int pColonne, final int pLigne) {

        _file = pColonne;
        _rank = pLigne;
        _index = pColonne + pLigne * RANK_COUNT;

        final StringBuilder sb = new StringBuilder(getClass().getSimpleName());
        sb.append("[file=").append((char) ('a' + getFile()));
        sb.append(",rank=").append((char) ('1' + getRank()));
        sb.append(']');
        _string = sb.toString();

        sb.delete(0, sb.length());
        sb.append((char) ('a' + getFile())).append((char) ('1' + getRank()));
        _fenString = sb.toString();
    }

    public int compareTo(final Square pCase) {
        return getFENString().compareTo(pCase.getFENString());
    }

    @Override
    public boolean equals(final Object pObjet) {
        if (pObjet == this) {
            return true;
        }

        if (!(pObjet instanceof Square)) {
            return false;
        }

        final Square o = (Square) pObjet;
        return _index == o._index;
    }

    public String getFENString() {
        return _fenString;
    }

    public int getFile() {
        return _file;
    }

    public int getIndex() {
        return _index;
    }

    public int getRank() {
        return _rank;
    }

    @Override
    public int hashCode() {
        return _index;
    }

    @Override
    public String toString() {
        return _string;
    }

    public static Square valueOf(final int pIndice) {
        return SQUARES[pIndice];
    }

    public static Square valueOf(final String pChaine) {
        return valueOf(pChaine.charAt(0) - 'a', pChaine.charAt(1) - '1');
    }

    public static Square valueOf(final int pColonne, final int pLigne) {

        return SQUARES[pColonne + pLigne * FILE_COUNT];
    }

    public static Square[] values() {
        final Square[] res = new Square[FILE_COUNT * RANK_COUNT];
        System.arraycopy(SQUARES, 0, res, 0, FILE_COUNT * RANK_COUNT);

        return res;
    }
}
